package com.model;

import com.model.attributes.AttributesInfo;
import com.model.field.FieldsInfo;
import com.model.method.MethodsInfo;
import com.model.pool.BaseConstantDecorate;
import com.model.structure.*;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * class文件结构
 * @author seven
 */
@Data
public class ClassInfo {
    /**
     * 该magic项目提供标识class文件格式的幻数；它具有价值0xCAFEBABE。
     */
    private Magic magic;
    /**
     * minor_version 和major_version项目 的值是此class文件的次要和主要版本号。主版本号和次版本号共同决定class文件格式的版本 。如果class文件的主要版本号为M，次要版本号为m，
     * 则将其class文件格式的版本表示为Mm。因此，class文件格式版本可以按字典顺序排序，例如1.5 <2.0 <2.1。
     * Java虚拟机实现可以支持class版本V的文件格式，当且仅如果V在于一些连续范围Mi.0 ≤ v ≤ Mj.m. Java虚拟机实现所遵循的Java SE平台的发行级别负责确定范围。
     * JDK 1.0.2版中的Oracle Java虚拟机实现支持class文件格式版本45.0至45.3（含）。JDK发行了1.1。*支持的class文件格式版本，范围从45.0到45.65535（含）。
     * 对于 k≥2，JDK版本1.k支持class45.0到44 + k.0（含）范围内的文件格式版本。
     */
    private MajorVersion majorVersion;
    /**
     * 次版本号
     */
    private MinorVersion minorVersion;
    /**
     * 该constant_pool_count项目的值等于表中的条目数constant_pool加一。一个constant_pool指数被认为是有效的，如果它比大于零且少constant_pool_count
     */
    private ConstantPoolCount poolCount;
    /**
     * 的constant_pool是结构的表（§4.4代表各种串常量，类和接口名，字段名，和本内提到的其他常量）ClassFile 结构和其子结构。每个constant_pool表条目的格式 由其第一个“标签”字节指示。
     * 该constant_pool表的索引从1到constant_pool_count-1。
     */
    private List<BaseConstantDecorate> poolList = new ArrayList<BaseConstantDecorate>();
    /**
     * 该access_flags项目的值是标志的掩码，该标志用于表示对该类或接口的访问许可权和属性。
     */
    private AccessFlags accessFlags;
    /**
     * 该this_class项目的值必须是constant_pool表中的有效索引。该constant_pool索引处的 条目必须是表示此 文件定义的类或接口的 CONSTANT_Class_info结构
     */
    private int thisClass;
    /**
     * 对于一个类，该项的值super_class 必须为零或必须是constant_pool表中的有效索引 。如果该项的值super_class非零，则constant_pool该索引处的 条目必须是一个 CONSTANT_Class_info结构，
     * 该结构表示此class文件定义的类的直接超类。直接超类或其任何超类都不能在 其结构项中 ACC_FINAL设置标志。 access_flagsClassFile
     * 如果该项的值super_class为零，则此class文件必须表示class Object，唯一的类或没有直接超类的接口。
     * 对于接口，该项的值 super_class必须始终是constant_pool表中的有效索引。该constant_pool 索引处的条目必须是CONSTANT_Class_info代表该类的结构Object。
     */
    private int superClass;
    /**
     * 项目的值interfaces_count给出此类或接口类型的直接超接口的数量。
     */
    private InterfaceCount faceCount;
    /**
     * interfaces数组 中的每个值都必须是constant_pool表中的有效索引。该 constant_pool在的每个值条目 ，
     * 其中0 ≤我 < ，必须是一个 代表一个接口，此类或接口类型的直接超接口结构，在源类型给定的左到右的顺序。 interfaces[i] interfaces_countCONSTANT_Class_info
     */
    private List<InterfaceInfo> faceList;
    /**
     * 项目的值fields_count给出field_info了fields表中结构的数量。这些field_info 结构表示此类或接口类型声明的所有字段，包括类变量和实例变量。
     */
    private FieldsCount fieldsCount;
    /**
     * fields表 中的每个值都必须是一个 field_info结构，以提供对该类或接口中字段的完整描述。
     * 该fields表仅包含此类或接口声明的那些字段。它不包括表示从超类或超接口继承的字段的项。
     */
    private List<FieldsInfo> fieldsList;
    /**
     * 项目的值methods_count给出method_info了methods表中结构的数量。
     */
    private MethodsCount methodsCount;
    /**
     * methods表 中的每个值都必须是一个 method_info结构（第4.6节），以提供对该类或接口中方法的完整描述。
     * 如果 在 结构项中未设置ACC_NATIVE和ACC_ABSTRACT标志，则还将提供实现该方法的Java虚拟机指令。 access_flagsmethod_info
     * 这些method_info结构表示该类或接口类型声明的所有方法，包括实例方法，类方法，实例初始化方法以及任何类或接口初始化的方法。
     * 该 methods表不包括代表从超类或超接口继承的方法的项。
     */
    private List<MethodsInfo> methodsList;
    /**
     * 项目的值attributes_count给出attributes此类表中的属性数。
     */
    private AttributesCount attributesCount;
    /**
     * 该attributes表的每个值都必须是一个 attribute_info结构（第4.7节）。
     * 表4.7-C列出 了该规范定义的出现在结构attributes表中的属性。 ClassFile
     * §4.7中给出了 有关定义为出现在结构 attributes表中的属性的规则 。 ClassFile
     * 第4.7.1节中给出attributes了有关ClassFile结构 表中非预定义属性的规则 。
     */
    private List<AttributesInfo> attributesList;
}
